package com.golden.procedure.service.impl;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.golden.procedure.client.EmployeeClientAPI;
import com.golden.procedure.clientDO.EmployeeDO;
import com.golden.procedure.dao.WorkAttachmentMapper;
import com.golden.procedure.dao.WorkOrderPhotographyMapper;
import com.golden.procedure.dao.WorkOrderPickMapper;
import com.golden.procedure.dao.WorkOrderPickTimesMapper;
import com.golden.procedure.dao.WorkPhotoFilmMapper;
import com.golden.procedure.dao.WorkPhotoProductMapper;
import com.golden.procedure.dao.WorkSeatSchedulingMapper;
import com.golden.procedure.domain.WorkCommentDO;
import com.golden.procedure.domain.WorkOrderDO;
import com.golden.procedure.domain.WorkOrderPickDO;
import com.golden.procedure.domain.WorkPhotoProductDO;
import com.golden.procedure.domain.WorkSeatSchedulingDO;
import com.golden.procedure.domain.WorkTaskHistoryDO;
import com.golden.procedure.domain.WorkerDO;
import com.golden.procedure.entity.WorkOrderPhotography;
import com.golden.procedure.entity.WorkOrderPick;
import com.golden.procedure.entity.WorkOrderPickExample;
import com.golden.procedure.entity.WorkOrderPickTimes;
import com.golden.procedure.entity.WorkOrderPickTimesExample;
import com.golden.procedure.entity.WorkPhotoFilmExample;
import com.golden.procedure.entity.WorkPhotoProduct;
import com.golden.procedure.entity.WorkPhotoProductExample;
import com.golden.procedure.entity.WorkSeatScheduling;
import com.golden.procedure.query.WorkPhotographyQueryDO;
import com.golden.procedure.query.WorkPickQueryDO;
import com.golden.procedure.query.WorkerQueryDO;
import com.golden.procedure.result.ResultDO;
import com.golden.procedure.result.ResultSupport;
import com.golden.procedure.service.ISiteService;
import com.golden.procedure.service.IWorkAttachmentService;
import com.golden.procedure.service.IWorkCommentService;
import com.golden.procedure.service.IWorkOrderPickService;
import com.golden.procedure.service.IWorkOrderService;
import com.golden.procedure.service.IWorkPhotoProductService;
import com.golden.procedure.service.IWorkSeatSchedulingService;
import com.golden.procedure.service.IWorkSiteSeatService;
import com.golden.procedure.service.IWorkTaskHistoryService;
import com.golden.procedure.service.IWorkerService;
import com.golden.procedure.util.BeanUtilsExtends;
import com.golden.procedure.util.BonConstant;
import com.golden.procedure.util.TaskDefKey;
import com.golden.procedure.util.Tools;

@Service("workOrderPickService")
public class WorkOrderPickService extends BaseService implements IWorkOrderPickService {

	@Autowired
	WorkOrderPickMapper workOrderPickMapper;
	@Autowired
	WorkSeatSchedulingMapper workSeatSchedulingMapper;
	@Autowired
	WorkOrderPickTimesMapper workOrderPickTimesMapper;
	@Autowired
	WorkAttachmentMapper workAttachmentMapper;
	@Autowired
	WorkPhotoProductMapper workPhotoProductMapper;
	@Autowired
	WorkPhotoFilmMapper workPhotoFilmMapper;
	@Autowired
	IWorkSeatSchedulingService workSeatSchedulingService;
	@Autowired
	IWorkerService workerService;
	@Autowired
	WorkOrderPhotographyMapper workOrderPhotographyMapper;
	@Autowired
	IWorkOrderService workOrderService;
	@Autowired
	ISiteService siteService;
	@Autowired
	IWorkSiteSeatService workSiteSeatService;
	@Autowired
	IWorkCommentService workCommentService;
	@Autowired
	IWorkTaskHistoryService workTaskHistoryService;
	@Autowired
	IWorkOrderPickService workOrderPickService;
	@Autowired
	IWorkAttachmentService workAttatchmentService;
	@Autowired
	IWorkPhotoProductService workPhotoProductService;
	@Autowired
	EmployeeClientAPI employeeClientAPI;

	/**
	 * 添加选片记录 <b>Description: 添加选片记录</b><br>
	 * 
	 * @param domain
	 * @return ResultDO
	 * @Note <b>Author:</b> Reading.Reagan <br>
	 *       <b>Date:</b> 2018年9月20日 下午3:43:42 <br>
	 *       <b>Version:</b> 1.0
	 */
	@Override
	public ResultDO add(WorkOrderPickDO domain) {

		ResultDO result = new ResultSupport();
		WorkOrderPick entity = new WorkOrderPick();
		if (!BeanUtilsExtends.copyProperties(entity, domain)) {
			result.setSuccess(false);
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("数据转换异常");
			return result;
		}
		if (isNumberInValid(domain.getWorkOrderID()) || isNumberInValid(domain.getSeatID())) {
			result.setSuccess(false);
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("数据转换异常");
			return result;
		}
		// 当前任务节点
		entity.setTaskDefID(TaskDefKey.SELECT_PHOTO.getKey());
		// 查询席位及服务人员信息
		if (!isNumberInValid(domain.getSeatID())) {
			ResultDO resultDO = workSeatSchedulingService.get(domain.getSeatID());
			if (!resultDO.isSuccess()) {
				result.setSuccess(false);
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("席位信息查询失败");
				return result;
			}
			WorkSeatSchedulingDO seatDO = (WorkSeatSchedulingDO) resultDO.getModel(ResultDO.FIRST_MODEL_KEY);
			// 上门组默认选片为拍摄时间
			entity.setPlanPickDate(Tools.getDatetime(seatDO.getSchedulingDate(), seatDO.getPlanStartOn()));
			// 预约状态：已确认预约
			entity.setPlanPickStatus(BonConstant.STATUS_TRUE);

			// 查询人员（默认规划师为选片人）
			WorkerQueryDO query = new WorkerQueryDO();
			query.setSiteSeatID(seatDO.getSiteSeatID());
			query.setRoleCode(BonConstant.ROLE_GUIHUA);
			ResultDO resultDO2 = workerService.queryBySiteSeat(query);
			if (resultDO2.isSuccess()) {
				List<WorkerDO> workerList = (List<WorkerDO>) resultDO2.getModel(ResultDO.FIRST_MODEL_KEY);
				if (null != workerList && workerList.size() > 0) {
					WorkerDO workerDO = workerList.get(0);
					entity.setEmployeeID(workerDO.getEmployeeID());
				}
			}

		} else {
			// 预约状态：未预约
			entity.setPlanPickStatus(BonConstant.STATUS_FALSE);
		}
		// 默认：未选片
		entity.setStatus(BonConstant.PICK_STATUS_WAITING);

		entity.setIsDelete(BonConstant.DB_NORMAL);
		entity.setCreatetime(Calendar.getInstance().getTime());

		int ret = workOrderPickMapper.insert(entity);
		if (ret < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("工单选片记录添加失败");
			result.setSuccess(false);
		}
		return result;
	}

	@Override
	public ResultDO query(WorkPhotographyQueryDO queryDO) {
		ResultDO result = new ResultSupport();
		// 查询条件：日期、员工/部门、客户姓名/电话及摄影组等，需要联合多表，同时需要分页，则使用mybatis自定义查询方式(有客户信息时，不显示空闲时段）
		List<WorkOrderPickDO> doList = new ArrayList<WorkOrderPickDO>();

		Map<String, Object> params = new HashMap<String, Object>();
		// 日期
		if (StringUtils.isNotEmpty(queryDO.getSchedulingDateStr())) {
			params.put("schedulingDate", new Date(Long.parseLong(queryDO.getSchedulingDateStr())));
		}
		// 用户ID
		if (!isNumberInValid(queryDO.getEmployeeID())) {
			params.put("employeeID", queryDO.getEmployeeID());
		}
		// 部门
		if (!isNumberInValid(queryDO.getOrgID())) {
			// 获取所有下级子部门
			List<Integer> ids = getOrgIDs(queryDO.getOrgID());
			params.put("orgIDs", ids);
		}
		// 客户姓名及电话
		if (StringUtils.isNotEmpty(queryDO.getNameOrTel())) {
			params.put("nameOrTel", "%" + queryDO.getNameOrTel() + "%");
		}

		if (queryDO.isPage()) {
			params.put("limitByPage", queryDO.getStart() + "," + queryDO.getPageRows());
			int count = workOrderPickMapper.countPickList(params);
			result.setModel(ResultDO.SECOND_MODEL_KEY, count);
		}

		List<WorkSeatScheduling> seatList = workSeatSchedulingMapper.selectPickList(params);
		if (null == seatList || seatList.size() < 1) {
			result.setModel(ResultDO.FIRST_MODEL_KEY, doList);
			result.setModel(ResultDO.THIRD_MODEL_KEY, doList.size());
			return result;
		}

		int num = 0;
		// 上门组名称
		Map<Integer, String> siteMap = new HashMap<Integer, String>();
		for (WorkSeatScheduling data : seatList) {
			WorkSeatSchedulingDO seat = getWorkSeatSchedulingDO(data);
			// 1.保存席位、日期、时段等信息
			WorkOrderPickDO entity = new WorkOrderPickDO();
			entity.setSiteSeatID(seat.getSiteSeatID());
			entity.setSeatID(seat.getId());
			entity.setPlanPickDate(seat.getSchedulingDate());
			entity.setPlanPickDateStr(seat.getSchedulingDateStr());
			entity.setPlanStartOn(seat.getPlanStartOn());
			entity.setPlanStartOnStr(seat.getPlanStartOnStr());

			if (BonConstant.SEAT_STATUS_ENABLE == seat.getStatus()) {
				// 闲置的席位，返回席位信息
				doList.add(entity);
				continue;
			}

			// 3.查询选片记录信息
			WorkOrderPickExample example = new WorkOrderPickExample();
			WorkOrderPickExample.Criteria criteria = example.createCriteria();
			criteria.andSeatIDEqualTo(seat.getId());
			criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
			List<WorkOrderPick> list = workOrderPickMapper.selectByExample(example);
			if (null == list || list.size() < 1) {
				// 无选片记录
				doList.add(entity);
				continue;
			}

			WorkOrderPick pick = list.get(0);
			WorkOrderPickDO pickDO = getWOrkOrderPickDO(pick);
			pickDO.setPlanStartOn(seat.getPlanStartOn());
			pickDO.setPlanStartOnStr(seat.getPlanStartOnStr());

			// 查询工单信息
			ResultDO resultDO2 = workOrderService.get(pickDO.getWorkOrderID());
			if (!resultDO2.isSuccess()) {
				// 查询失败
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("工单信息查询失败");
				result.setSuccess(false);
				return result;
			}
			WorkOrderDO workOrderDO = (WorkOrderDO) resultDO2.getModel(ResultDO.FIRST_MODEL_KEY);
			pickDO.setWorkOrder(workOrderDO);

			// 查询工单服务人员
			WorkerQueryDO query = new WorkerQueryDO();
			query.setSiteSeatID(seat.getSiteSeatID());
			ResultDO res = workerService.queryBySiteSeat(query);
			if (!res.isSuccess()) {
				// 查询失败
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("工单服务人员查询失败");
				result.setSuccess(false);
				return result;
			}
			List<WorkerDO> workerList = (List<WorkerDO>) res.getModel(ResultDO.FIRST_MODEL_KEY);
			for (WorkerDO workerDO : workerList) {
				// 摄影师
				if (BonConstant.ROLE_SHEYING.equals(workerDO.getRoleCode())) {
					// 拍摄时间
					WorkOrderPhotography photography = workOrderPhotographyMapper
							.selectByPrimaryKey(pickDO.getWorkPhotographyID());
					workerDO.setCreatetime(photography.getShotDate().getTime() + "");
					pickDO.setPhotographer(workerDO);
					continue;
				}
				// 选片师/规划师
				if (workerDO.getEmployeeID().equals(pickDO.getEmployeeID())) {
					pickDO.setEmployeeName(workerDO.getEmployeeName());
				}
			}

			// 拍摄地点（默认上门组地点）
			if (siteMap.containsKey(seat.getSiteID())) {
				pickDO.setSiteName(siteMap.get(seat.getSiteID()));
			} else {
				String siteName = siteService.getName(seat.getSiteID());
				if (null != siteName) {
					siteMap.put(seat.getSiteID(), siteName);
					pickDO.setSiteName(siteService.getName(seat.getSiteID()));
				}
			}
			// 可选照片数量
			pickDO.setPickPhotoNum(workAttatchmentService.countPickNum(pickDO.getWorkPhotographyID()));
			doList.add(pickDO);
			num++;
		}

		result.setModel(ResultDO.FIRST_MODEL_KEY, doList);
		result.setModel(ResultDO.THIRD_MODEL_KEY, num);
		return result;
	}

	/** 查询拍摄列表 （多条件多表查询方式） */
	public ResultDO queryByCondition(WorkPhotographyQueryDO queryDO) {
		ResultDO result = new ResultSupport();
		List<WorkOrderPickDO> doList = new ArrayList<WorkOrderPickDO>();

		// 查询满足条件的拍摄记录
		Map<String, Object> params = new HashMap<String, Object>();
		if (StringUtils.isNotEmpty(queryDO.getSchedulingDateStr())) {
			params.put("schedulingDate", new Date(Long.parseLong(queryDO.getSchedulingDateStr())));
		}
		if (!isNumberInValid(queryDO.getEmployeeID())) {
			params.put("employeeID", queryDO.getEmployeeID());
		}
		if (!isNumberInValid(queryDO.getOrgID())) {
			// 获取所有下级子部门
			List<Integer> ids = getOrgIDs(queryDO.getOrgID());
			params.put("orgIDs", ids);
		}
		if (StringUtils.isNotEmpty(queryDO.getNameOrTel())) {
			params.put("nameOrTel", "%" + queryDO.getNameOrTel() + "%");
		}

		int count = 0;
		if (queryDO.isPage()) {
			params.put("limitByPage", queryDO.getStart() + "," + queryDO.getPageRows());
			count = workOrderPickMapper.countPickList(params);
		}

		List<WorkOrderPick> list = workOrderPickMapper.selectPickList(params);
		if (null == list || list.size() < 1) {
			result.setModel(ResultDO.FIRST_MODEL_KEY, doList);
			result.setModel(ResultDO.SECOND_MODEL_KEY, count);
			result.setModel(ResultDO.THIRD_MODEL_KEY, 0);
			return result;
		}

		// 填充数据
		for (WorkOrderPick data : list) {

			WorkOrderPickDO pickDO = getWOrkOrderPickDO(data);
			// 查询工单信息
			ResultDO resultDO2 = workOrderService.get(pickDO.getWorkOrderID());
			if (!resultDO2.isSuccess()) {
				// 查询失败
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("工单信息查询失败");
				result.setSuccess(false);
				return result;
			}
			WorkOrderDO workOrderDO = (WorkOrderDO) resultDO2.getModel(ResultDO.FIRST_MODEL_KEY);
			pickDO.setWorkOrder(workOrderDO);

			// 查询席位
			ResultDO resultDO = workSeatSchedulingService.get(data.getSeatID());
			if (!resultDO.isSuccess()) {
				// 工单及预约信息查询失败
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("席位信息查询失败");
				result.setSuccess(false);
				return result;
			}
			WorkSeatSchedulingDO seat = (WorkSeatSchedulingDO) resultDO.getModel(ResultDO.FIRST_MODEL_KEY);
			pickDO.setPlanStartOn(seat.getPlanStartOn());
			pickDO.setPlanStartOnStr(seat.getPlanStartOnStr());

			// 查询工单服务人员
			WorkerQueryDO query = new WorkerQueryDO();
			query.setSiteSeatID(seat.getSiteSeatID());
			ResultDO res = workerService.queryBySiteSeat(query);
			if (!res.isSuccess()) {
				// 查询失败
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("工单服务人员查询失败");
				result.setSuccess(false);
				return result;
			}
			List<WorkerDO> workerList = (List<WorkerDO>) res.getModel(ResultDO.FIRST_MODEL_KEY);
			for (WorkerDO workerDO : workerList) {
				// 摄影师
				if (BonConstant.ROLE_SHEYING.equals(workerDO.getRoleCode())) {
					// 拍摄时间
					WorkOrderPhotography photography = workOrderPhotographyMapper
							.selectByPrimaryKey(pickDO.getWorkPhotographyID());
					workerDO.setCreatetime(photography.getShotDate().getTime() + "");
					pickDO.setPhotographer(workerDO);
					continue;
				}
				if (workerDO.getEmployeeID().equals(pickDO.getEmployeeID())) {
					pickDO.setEmployeeName(workerDO.getEmployeeName());
				}
			}
			// 拍摄地点（默认上门组地点）
			// 上门组名称
			pickDO.setSiteName(siteService.getName(seat.getSiteID()));
			// 可选照片数量
			pickDO.setPickPhotoNum(workAttatchmentService.countPickNum(pickDO.getWorkPhotographyID()));
			doList.add(pickDO);
		}

		result.setModel(ResultDO.FIRST_MODEL_KEY, doList);
		result.setModel(ResultDO.SECOND_MODEL_KEY, count > 0 ? count : doList.size());
		result.setModel(ResultDO.THIRD_MODEL_KEY, doList.size());
		return result;
	}

	@Override
	public ResultDO record(WorkCommentDO domain) {
		ResultDO result = new ResultSupport();

		// 1. 数据验证
		if (isNumberInValid(domain.getId()) || null == domain.getStatus()) {
			// 席位查询失败
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		// 1.判断是否有未提交的加选订单，如果有，则不允许完成
		WorkOrderPickTimesExample example = new WorkOrderPickTimesExample();
		WorkOrderPickTimesExample.Criteria criteria = example.createCriteria();
		criteria.andWorkOrderPickIDEqualTo(domain.getId());
		criteria.andStatusNotEqualTo(BonConstant.PICK_ORDER_STATUS_PAID);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		int ret = workOrderPickTimesMapper.countByExample(example);
		if (ret > 0) {
			// TODO: 通过订单接口，查询未提交和已提交未支付的加选订单是否有修改，有修改则不允许提交，无改动则删除此业务单号
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("有未完成的加选订单");
			result.setSuccess(false);
			return result;
		}
		// 2. 更新选片记录表：选片状态(已完成的任务，不允许再操作)
		WorkOrderPick entity = workOrderPickMapper.selectByPrimaryKey(domain.getId());
		if (entity.getStatus() != BonConstant.PICK_STATUS_WAITING
				&& entity.getStatus() != BonConstant.PICK_STATUS_ING) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("本次选片已完成");
			result.setSuccess(false);
			return result;
		}
		// 选片任务完成状态
		entity.setStatus(domain.getStatus());
		entity.setModifitime(Calendar.getInstance().getTime());
		entity.setModifiID(domain.getAuthorID());
		entity.setModifi(domain.getAuthor());
		// 选片服务完成时，记录时间
		Long duration = 0L; // 选片时长
		if (null != entity.getPickDate()) {
			Long start = entity.getPickDate().getTime();
			Long current = System.currentTimeMillis();
			duration = current - start;
		}
		if (domain.getStatus() != BonConstant.PICK_STATUS_ING) {
			entity.setPickDuration(duration);
		}

		ret = workOrderPickMapper.updateByPrimaryKeySelective(entity);
		if (ret < 1) {
			// 选片记录状态修改失败
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("选片记录修改失败");
			result.setSuccess(false);
			return result;
		}

		// TODO: 3. activity完成此节点任务

		// 4. 更新工单表：当前任务节点
		WorkOrderDO workOrder = new WorkOrderDO();
		String statusName = "选片完成";
		// 选片状态：0-未选,1-进行中,2-重拍,3-补拍,4-改期,5-完成，-1取消
		if (domain.getStatus() == BonConstant.PICK_STATUS_OK) {
			// 下一步设计制作
			workOrder.setTaskDefID(TaskDefKey.DESIGN_PRODUCT.getKey()); // 下一步
		} else {
			// 未完成选片
			workOrder.setOrderStatus(domain.getStatus());
			if (domain.getStatus() == BonConstant.PICK_STATUS_REPHOTOGRAPH) {
				// 重拍
				workOrder.setIsRePhotograph(BonConstant.STATUS_TRUE);
				workOrder.setTaskDefID(TaskDefKey.ORDER_SCHEDULE.getKey()); // 当前任务：上摄控
				statusName = "待重拍";
			} else if (domain.getStatus() == BonConstant.PICK_STATUS_RESHOT) {
				// 补拍
				workOrder.setIsReshot(BonConstant.STATUS_TRUE);
				workOrder.setTaskDefID(TaskDefKey.ORDER_SCHEDULE.getKey()); // 当前任务：上摄控
				statusName = "待补拍";
			} else if (domain.getStatus() == BonConstant.PICK_STATUS_CHANGEDATE) {
				// 改期
				workOrder.setTaskDefID(TaskDefKey.SELECT_PHOTO.getKey()); // 当前任务：选片（待重新预约选片时间）
				workOrder.setIsChangeDate(BonConstant.STATUS_TRUE);
				workOrder.setTaskDefID(TaskDefKey.ORDER_SCHEDULE.getKey()); // 当前任务：上摄控
				statusName = "改期";
			} else if (domain.getStatus() == BonConstant.PICK_STATUS_CANCLE) {
				// TODO:选片取消
				statusName = "选片取消";
			} else {
				// TODO:未完成选片
				statusName = "未完成";
			}
		}
		// workOrder.setFlag(domain.getFlag()); // 特殊标记
		workOrder.setId(entity.getWorkOrderID());
		workOrder.setModifiID(domain.getAuthorID());
		workOrder.setModifi(domain.getAuthor());
		ResultDO resultDO1 = workOrderService.edit(workOrder);
		if (!resultDO1.isSuccess()) {
			// 工单状态修改失败
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("工单状态修改失败");
			result.setSuccess(false);
			return result;
		}

		// 5.写入工单任务记录表、工单执行备注表
		// 5.1备注表
		WorkCommentDO commentDO = new WorkCommentDO();
		commentDO.setWorkOrderID(entity.getWorkOrderID());
		commentDO.setProcessInstanceID(entity.getProcessInstanceID());
		commentDO.setTaskDefID(TaskDefKey.SELECT_PHOTO.getKey()); // 选片
		commentDO.setTaskName(TaskDefKey.SELECT_PHOTO.getName());
		commentDO.setTaskID(entity.getTaskID()); // 从acitivti获取
		commentDO.setType(BonConstant.COMMENT_TYPE_REMARK); // 0备注；1事件
		if (StringUtils.isNotEmpty(domain.getRemark())) {
			commentDO.setRemark(statusName + ":" + domain.getRemark());
		} else {
			commentDO.setRemark(statusName);
		}
		// commentDO.setFlag(domain.getFlag()); // 0普通；1特殊
		commentDO.setAuthorID(domain.getAuthorID());
		commentDO.setAuthor(domain.getAuthor());
		workCommentService.add(commentDO);

		// 5.2工单任务记录表
		WorkTaskHistoryDO taskHistoryDO = new WorkTaskHistoryDO();
		taskHistoryDO.setWorkOrderID(entity.getWorkOrderID());
		taskHistoryDO.setProcessInstanceID(entity.getProcessInstanceID());
		taskHistoryDO.setTaskDefID(TaskDefKey.SELECT_PHOTO.getKey()); // 拍摄
		taskHistoryDO.setTaskName(TaskDefKey.SELECT_PHOTO.getName());
		taskHistoryDO.setTaskID(entity.getTaskID()); // 从acitivti获取
		taskHistoryDO.setSchedulingdate(entity.getPickDate());
		taskHistoryDO.setStartOn(entity.getPickDate());
		taskHistoryDO.setEndOn(Calendar.getInstance().getTime());
		taskHistoryDO.setDuration(duration);
		taskHistoryDO.setStatus(domain.getStatus() != BonConstant.PICK_STATUS_OK ? 0 : 1);
		taskHistoryDO.setAuthorID(domain.getAuthorID());
		taskHistoryDO.setAuthor(domain.getAuthor());
		workTaskHistoryService.add(taskHistoryDO);

		return result;
	}

	/**
	 * 进入选片
	 * 
	 * @Method: startPick
	 * @Description: 1.未开始的选片：记录选片时间，创建新的业务单号，拷贝入底数据，进入选片； 2.进行中的选片：
	 *               查看最新的业务单号是否未提交，是：则沿用单号及片源，同步入底照片数据，进入选片；
	 *               查看最新的业务单号是否已提交但未支付，是：则沿用单号及片源，不允许编辑，进入选片页面浏览结果数据；
	 *               查看最新的业务单号是否已支付，是：则创建新的业务单号,沿用上一次的片源，拷贝上一次的入底及入册数据，
	 *               同时同步最新的照片数据，进入选片； 3.已完成、重拍、补拍、改期、取消的选片： 查看是否有完成的业务单号：
	 *               有，则不允许编辑，只能查看本次业务单号的选片信息； 无，则提示：无选片记录；
	 * @param domain
	 * @return
	 * @see com.golden.procedure.service.IWorkOrderPickService#startPick(com.golden.procedure.domain.WorkPhotoProductDO)
	 */
	@Override
	public ResultDO startPick(WorkPhotoProductDO domain) {
		ResultDO result = new ResultSupport();

		// 1. 数据验证
		if (isNumberInValid(domain.getWorkOrderPickID())) {
			// 席位查询失败
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		// 2. 更新选片记录表：选片开始时间、选片状态等
		WorkOrderPick entity = workOrderPickMapper.selectByPrimaryKey(domain.getWorkOrderPickID());
		if (BonConstant.PICK_STATUS_WAITING == entity.getStatus()) {
			// 刚开始选片，更新选片状态：进行中，设置开始选片的时间
			entity.setStatus(BonConstant.PICK_STATUS_ING);
			entity.setPickDate(new Date());
			entity.setModifitime(Calendar.getInstance().getTime());

			int ret = workOrderPickMapper.updateByPrimaryKeySelective(entity);
			if (ret < 1) {
				// 选片记录状态修改失败
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("拍摄记录状态修改失败");
				result.setSuccess(false);
				return result;
			}
		}

		// 查询加选订单列表，查看是否有正在选片的业务单号，如果有，则沿用之前的业务单号，未提交则继续选片；已提交订单，则只能浏览，不能操作；
		// 如果没有，则重新创建业务单号；
		WorkOrderPickTimes timesEntity = new WorkOrderPickTimes();

		WorkOrderPickTimesExample example = new WorkOrderPickTimesExample();
		WorkOrderPickTimesExample.Criteria criteria = example.createCriteria();
		criteria.andWorkOrderIDEqualTo(entity.getWorkOrderID());
		criteria.andWorkOrderPickIDEqualTo(domain.getWorkOrderPickID());
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);

		example.setOrderByClause(" id desc ");
		List<WorkOrderPickTimes> list = workOrderPickTimesMapper.selectByExample(example);

		// 本次新业务单号
		String businessNo = "";
		// 上一次业务单号
		String lastBusinessNo = null;
		// 片源（沿用以前的片源，第一次选片，使用页面选取的片源）
		Integer source = domain.getSource();
		// 是否允许选片编辑（已完成的选片任务、选片任务进行中但加选订单已提交的不支持编辑）
		Integer editEnable = BonConstant.STATUS_TRUE;
		if (null != list && list.size() > 0) {
			// 已有业务单号
			timesEntity = list.get(0);
			source = timesEntity.getSource(); // 沿用上一次的片源
			// 记录最近一次的业务单号
			lastBusinessNo = timesEntity.getBusinessNo();
			// 新业务单号默认为上一次的业务单号（如果业务单号已支付完成，则重新创建业务单号）
			businessNo = timesEntity.getBusinessNo();

			if (BonConstant.PICK_STATUS_ING == entity.getStatus()) {
				// 当前加选任务状态： 进行中
				if (BonConstant.PICK_ORDER_STATUS_PAID == timesEntity.getStatus()) {
					// 已完成支付，新开业务单号(业务单号从订单处获取)；
					businessNo = getBusinessNo(entity.getWorkOrderID(), entity.getId());
				} else if (BonConstant.PICK_ORDER_STATUS_COMMIT == timesEntity.getStatus()) {
					// 未提交、已提交时时沿用上一次的业务单号； 已提交的加选订单，只能查看不能编辑
					editEnable = BonConstant.STATUS_FALSE;
				}
			} else {
				// 选片任务已完成时，不允许编辑，使用最后一次业务单号
				editEnable = BonConstant.STATUS_FALSE;
			}
		} else {
			// 无业务单号
			if (BonConstant.PICK_STATUS_ING == entity.getStatus()) {
				// 从订单处获取新的销售业务单号
				businessNo = getBusinessNo(entity.getWorkOrderID(), entity.getId());
			} else {
				// 选片任务已完成，但是没有加选订单时，提示
				editEnable = BonConstant.STATUS_FALSE;
				// 选片记录状态修改失败
				result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
				result.setErrorMsg("选片任务已结束，无选片记录");
				result.setSuccess(false);
				return result;

			}
		}

		if (editEnable == BonConstant.STATUS_TRUE && !businessNo.equals(lastBusinessNo)) {
			// 新增业务单号
			timesEntity = new WorkOrderPickTimes();
			timesEntity.setWorkOrderID(entity.getWorkOrderID());
			timesEntity.setWorkOrderPickID(entity.getId());
			timesEntity.setBusinessNo(businessNo);
			timesEntity.setEmployeeID(entity.getEmployeeID());
			EmployeeDO employeeDO = getEmployee(entity.getEmployeeID());
			if (null != employeeDO) {
				timesEntity.setOrgID(employeeDO.getOrgId());
			}
			timesEntity.setSource(source);
			timesEntity.setStatus(BonConstant.PICK_ORDER_STATUS_ING);
			timesEntity.setIsDelete(BonConstant.DB_NORMAL);
			timesEntity.setCreatetime(Calendar.getInstance().getTime());
			workOrderPickTimesMapper.insert(timesEntity);

			// 拷贝入册数据
			if (null != lastBusinessNo) {
				// 拷贝上一次的入册数据
				WorkPhotoProductExample productExample = new WorkPhotoProductExample();
				WorkPhotoProductExample.Criteria productCriteria = productExample.createCriteria();
				productCriteria.andBusinessNoEqualTo(lastBusinessNo);
				productCriteria.andWorkOrderIDEqualTo(entity.getWorkOrderID());
				productCriteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
				List<WorkPhotoProduct> products = workPhotoProductMapper.selectByExample(productExample);
				for (WorkPhotoProduct data : products) {
					data.setId(null);
					data.setBusinessNo(businessNo);
					data.setCreatetime(Calendar.getInstance().getTime());
				}
				workPhotoProductMapper.insertBatch(products);
			}
		}
		if (editEnable == BonConstant.STATUS_TRUE) {
			// 新业务单号：拷贝上一次入底数据；第一次选片时，从片源初始化入底（源片+自备片）数据；相同业务单号
			workPhotoProductService.initPhotoFilm(entity.getWorkOrderID(), entity.getWorkPhotographyID(), businessNo,
					lastBusinessNo, source);
		}

		// 返回本次的业务单号、片源及是否允许编辑标志
		WorkOrderPickDO pickDO = getWOrkOrderPickDO(entity);
		pickDO.setBusinessNo(businessNo);
		pickDO.setSource(source);
		pickDO.setEditEnable(editEnable);

		result.setModel(ResultDO.FIRST_MODEL_KEY, pickDO);

		return result;
	}

	@Override
	public ResultDO queryByBusinessNo(WorkPickQueryDO queryDO) {

		ResultDO result = new ResultSupport();

		// 查询业务单号
		WorkOrderPickTimesExample timesExample = new WorkOrderPickTimesExample();
		WorkOrderPickTimesExample.Criteria timesCriteria = timesExample.createCriteria();
		if (!isNumberInValid(queryDO.getEmployeeID())) {
			timesCriteria.andEmployeeIDEqualTo(queryDO.getEmployeeID());
		}
		if (!isNumberInValid(queryDO.getOrgID())) {
			// 通过部门id查询部门内所有子部门id
			List<Integer> ids = getOrgIDs(queryDO.getOrgID());
			if (ids.size() > 0) {
				timesCriteria.andOrgIDIn(ids);
			}
		}
		if (null != queryDO.getStatus()) {
			timesCriteria.andStatusEqualTo(queryDO.getStatus());
		}
		timesExample.setOrderByClause(" id desc ");

		if (queryDO.isPage()) {
			timesExample.setLimitByPage(queryDO.getStart() + "," + queryDO.getPageRows());
			int count = workOrderPickTimesMapper.countByExample(timesExample);
			result.setModel(ResultDO.SECOND_MODEL_KEY, count);
		}

		List<WorkOrderPickTimes> list = workOrderPickTimesMapper.selectByExample(timesExample);

		List<WorkOrderPickDO> doList = new ArrayList<WorkOrderPickDO>();
		Map<Integer, WorkOrderPickDO> pickMap = new HashMap<Integer, WorkOrderPickDO>();
		Map<Integer, WorkOrderDO> orderMap = new HashMap<Integer, WorkOrderDO>();
		for (WorkOrderPickTimes data : list) {
			// 查询对应选片记录
			WorkOrderPickDO pickDO = new WorkOrderPickDO();

			if (pickMap.containsKey(data.getWorkOrderPickID())) {
				pickDO = pickMap.get(data.getWorkOrderPickID());
			} else {
				WorkOrderPick pick = workOrderPickMapper.selectByPrimaryKey(data.getWorkOrderPickID());
				pickDO = getWOrkOrderPickDO(pick);
				if (null != pickDO) {
					pickMap.put(pick.getId(), pickDO);
				} else {
					// 选片记录不存在
					result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
					result.setErrorMsg("选片记录查询失败");
					result.setSuccess(false);
					return result;
				}
			}

			// 设置业务单号相关信息
			pickDO.setBusinessNo(data.getBusinessNo());
			pickDO.setTotalAmount(data.getAmount()); // 金额
			pickDO.setStatus(data.getStatus()); // 状态
			if (data.getStatus() == BonConstant.PICK_ORDER_STATUS_COMMIT) {
				pickDO.setStatusName("已提交");
			} else if (data.getStatus() == BonConstant.PICK_ORDER_STATUS_ING) {
				pickDO.setStatusName("已支付");
			} else {
				// 未提交
				pickDO.setStatusName("未提交");
				// TODO: 从订单处获取目前加选订单的金额
				pickDO.setTotalAmount(new BigDecimal(1000));
			}
			// 查询销售员工
			pickDO.setEmployeeID(data.getEmployeeID());
			pickDO.setEmployeeName(getEmployee(data.getEmployeeID()).getRealName());

			// 查询工单记录
			if (orderMap.containsKey(data.getWorkOrderID())) {
				pickDO.setWorkOrder(orderMap.get(data.getWorkOrderID()));
			} else {
				// 查询工单信息
				ResultDO resultDO = workOrderService.get(data.getWorkOrderID());
				if (!resultDO.isSuccess()) {
					// 工单信息查询失败
					result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
					result.setErrorMsg("工单信息查询失败");
					result.setSuccess(false);
					return result;
				}
				WorkOrderDO orderDO = (WorkOrderDO) resultDO.getModel(ResultDO.FIRST_MODEL_KEY);
				orderMap.put(data.getWorkOrderID(), orderDO);
				pickDO.setWorkOrder(orderDO);
			}

			doList.add(pickDO);
		}

		result.setModel(ResultDO.FIRST_MODEL_KEY, doList);
		return result;
	}

	@Override
	public ResultDO cancelPickOrder(WorkOrderPickDO domain) {
		ResultDO result = new ResultSupport();
		// 1. 数据验证(工单id、业务单号)
		if (isNumberInValid(domain.getWorkOrderID()) || StringUtils.isEmpty(domain.getBusinessNo())) {
			// 席位查询失败
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		// 2. 修改对应销售业务单号的状态
		WorkOrderPickTimesExample example = new WorkOrderPickTimesExample();
		WorkOrderPickTimesExample.Criteria criteria = example.createCriteria();
		criteria.andWorkOrderIDEqualTo(domain.getWorkOrderID());
		criteria.andBusinessNoEqualTo(domain.getBusinessNo());
		criteria.andStatusEqualTo(BonConstant.PICK_ORDER_STATUS_COMMIT);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);

		WorkOrderPickTimes entity = new WorkOrderPickTimes();
		// 状态：选片中
		entity.setStatus(BonConstant.PICK_ORDER_STATUS_ING);
		entity.setModifitime(Calendar.getInstance().getTime());

		int ret = workOrderPickTimesMapper.updateByExampleSelective(entity, example);
		if (ret < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("加选订单取消失败");
			result.setSuccess(false);
		}
		// TODO: 3. 通知订单模块

		return result;
	}

	@Override
	public ResultDO delPickOrder(WorkOrderPickDO domain) {

		ResultDO result = new ResultSupport();
		// 1. 数据验证(工单id、业务单号)
		if (isNumberInValid(domain.getWorkOrderID()) || StringUtils.isEmpty(domain.getBusinessNo())) {
			// 席位查询失败
			result.setErrorCode(ResultDO.PARAM_ERROR);
			result.setErrorMsg("参数错误");
			result.setSuccess(false);
			return result;
		}

		// 1. 删除入册
		WorkPhotoProductExample example = new WorkPhotoProductExample();
		WorkPhotoProductExample.Criteria criteria = example.createCriteria();
		criteria.andWorkOrderIDEqualTo(domain.getWorkOrderID());
		criteria.andBusinessNoEqualTo(domain.getBusinessNo());
		int ret = workPhotoProductMapper.deleteByExample(example);

		// 2. 删除入底
		WorkPhotoFilmExample filmExample = new WorkPhotoFilmExample();
		WorkPhotoFilmExample.Criteria filmCriteria = filmExample.createCriteria();
		filmCriteria.andWorkOrderIDEqualTo(domain.getWorkOrderID());
		filmCriteria.andBusinessNoEqualTo(domain.getBusinessNo());
		ret = workPhotoFilmMapper.deleteByExample(filmExample);
		if (ret < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("入底数据删除错误");
			result.setSuccess(false);
			return result;
		}

		// 3. 删除加选订单
		WorkOrderPickTimesExample timesExample = new WorkOrderPickTimesExample();
		WorkOrderPickTimesExample.Criteria timesCriteria = timesExample.createCriteria();
		timesCriteria.andWorkOrderIDEqualTo(domain.getWorkOrderID());
		timesCriteria.andBusinessNoEqualTo(domain.getBusinessNo());
		ret = workOrderPickTimesMapper.deleteByExample(timesExample);
		if (ret < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("加选订单删除错误");
			result.setSuccess(false);
			return result;
		}

		// TODO：4. 通知订单模块

		return result;
	}

	@Override
	public String getBusinessNo(Integer workOrderPickID) {

		// 按照id排序，获取最后一个支付成功的businessNo
		WorkOrderPickTimesExample example = new WorkOrderPickTimesExample();
		WorkOrderPickTimesExample.Criteria criteria = example.createCriteria();
		criteria.andWorkOrderPickIDEqualTo(workOrderPickID);
		criteria.andStatusEqualTo(BonConstant.PICK_ORDER_STATUS_PAID);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
		example.setOrderByClause(" id desc ");
		List<WorkOrderPickTimes> list = workOrderPickTimesMapper.selectByExample(example);
		if (null != list && list.size() > 0) {
			return list.get(0).getBusinessNo();
		}
		return null;
	}

	@Override
	public ResultDO updateAmount(WorkOrderPickDO domain) {
		ResultDO result = new ResultSupport();

		// 1. 更新加选订单数据(更新状态、金额）
		WorkOrderPickTimesExample example = new WorkOrderPickTimesExample();
		WorkOrderPickTimesExample.Criteria criteria = example.createCriteria();
		criteria.andBusinessNoEqualTo(domain.getBusinessNo());
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);

		WorkOrderPickTimes entity = new WorkOrderPickTimes();
		entity.setStatus(domain.getStatus());
		entity.setAmount(domain.getTotalAmount());
		entity.setEmployeeID(domain.getEmployeeID());

		List<WorkOrderPickTimes> list = workOrderPickTimesMapper.selectByExample(example);
		if (null == list || list.size() < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("加选订单查询失败");
			result.setSuccess(false);
			return result;
		}
		int ret = workOrderPickTimesMapper.updateByExampleSelective(entity, example);
		if (ret < 1) {
			result.setErrorCode(ResultDO.SYSTEM_EXCEPTION_ERROR);
			result.setErrorMsg("加选订单更新失败");
			result.setSuccess(false);
			return result;
		}

		// 2. 累计加选订单金额，更新选片记录表
		// 查询已支付的加选订单
		entity = list.get(0);
		example.clear();
		criteria = example.createCriteria();
		criteria.andWorkOrderIDEqualTo(entity.getWorkOrderID());
		criteria.andWorkOrderPickIDEqualTo(entity.getWorkOrderPickID());
		criteria.andStatusEqualTo(BonConstant.PICK_ORDER_STATUS_PAID);
		criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);

		list = workOrderPickTimesMapper.selectByExample(example);

		BigDecimal totalAmount = new BigDecimal(0);
		for (WorkOrderPickTimes data : list) {
			// 累计加选订单金额，更新选片记录表
			totalAmount = totalAmount.add(data.getAmount());
		}
		if (totalAmount.compareTo(new BigDecimal(0)) > 0) {
			// 累计加选订单金额，更新选片记录表
			WorkOrderPick pick = new WorkOrderPick();
			pick.setId(entity.getWorkOrderPickID());
			pick.setTotalAmount(totalAmount);
			workOrderPickMapper.updateByPrimaryKeySelective(pick);
		}

		return result;
	}

	/** TODO： 从订单处获取销售业务单号 */
	public String getBusinessNo(Integer workOrderID, Integer workOrderPickID) {
		return workOrderID + "_" + workOrderPickID + "_" + System.currentTimeMillis();
	}

	/** 获取前一次选片的片源 */
	public Integer getSource(String businessNo) {

		if (StringUtils.isNotEmpty(businessNo)) {
			WorkOrderPickTimesExample example = new WorkOrderPickTimesExample();
			WorkOrderPickTimesExample.Criteria criteria = example.createCriteria();
			criteria.andBusinessNoEqualTo(businessNo);
			criteria.andIsDeleteEqualTo(BonConstant.DB_NORMAL);
			example.setOrderByClause(" id desc ");
			List<WorkOrderPickTimes> list = workOrderPickTimesMapper.selectByExample(example);
			if (null != list && list.size() > 0) {
				return list.get(0).getSource();
			}
		}
		return -1;
	}
}
